package com.polaris.live.utils.state

import androidx.annotation.IntDef
import androidx.recyclerview.widget.RecyclerView
import com.polaris.live.common.constant.AppConst
import com.polaris.live.constant.LiveConst
import com.polaris.live.constant.UserConst
import com.polaris.live.im.sfs.bean.live.ext.UserBasicVo
import com.polaris.live.im.sfs.bean.pusher.UserState
import com.polaris.live.im.sfs.bean.pusher.UserStateMessage
import com.polaris.live.resp.back_resp.InfoOtherResp
import com.polaris.live.utils.CommonUtils.toBoolean
import com.polaris.live.utils.RecyclerUtils.getFirstPosition
import com.polaris.live.utils.RecyclerUtils.getLastPosition
import kotlin.math.max
import kotlin.math.min

/**
 * UserStateUtils
 *
 * @author Created by lucas on 2023/11/1 11:52
 */
object UserStateUtils {
    const val USER_STATE_ONLINE = 0         //在线
    const val USER_STATE_OFFLINE = 1        //离线
    const val USER_STATE_BUSY = 2           //忙碌
    const val USER_STATE_LIVE = 3           //直播
    const val USER_STATE_MATCH = 4          //匹配
    const val USER_STATE_PARTY = 5          //派对 -> 语音房
    const val USER_STATE_GAME = 6           //游戏
    const val USER_GAME_WAITING = 7         //游戏状态 -> 等待中
    const val USER_GAME_PLAYING = 8         //游戏状态 -> 游戏中
    const val USER_STATE_PARTY_VIDEO = 9    //派对 -> 视频房

    @IntDef(
        USER_STATE_ONLINE,
        USER_STATE_OFFLINE,
        USER_STATE_BUSY,
        USER_STATE_LIVE,
        USER_STATE_MATCH,
        USER_STATE_PARTY,
        USER_STATE_GAME,
        USER_GAME_WAITING,
        USER_GAME_PLAYING,
        USER_STATE_PARTY_VIDEO
    )
    annotation class UserStatus


    /**
     * 处理用户状态
     */
    @UserStatus
    fun resolveUserState(userBasic: UserBasicVo): Int {
        return invokeResolveUserState(
            userBasic.online,
            userBasic.living,
            userBasic.liveType,
            userBasic.calling,
            userBasic.partyGaming,
            userBasic.partyGameSite
        )
    }

    /**
     * 处理用户状态(各个列表中展示的状态)
     */
    @UserStatus
    fun resolveListUserState(userBasic: UserBasicVo): Int {
        return invokeListUserState(
            userBasic.online,
            userBasic.living,
            userBasic.liveType,
            userBasic.calling,
            userBasic.partyGameStatus,
            userBasic.partyGaming,
            userBasic.partyGameSite
        )
    }

    /**
     * 处理用户状态
     */
    @UserStatus
    fun resolveUserState(userState: UserState): Int {
        return invokeResolveUserState(
            userState.online,
            userState.living,
            userState.liveType,
            userState.calling,
            userState.partyGaming,
            userState.partyGameSite
        )
    }

    /**
     * 处理用户状态
     */
    @UserStatus
    fun resolveUserState(userInfo: InfoOtherResp): Int {
        return invokeResolveUserState(
            userInfo.online,
            if (userInfo.live?.living == true) 1 else 0,
            userInfo.live?.liveType,
            if (userInfo.call?.calling == true) 1 else 0,
            userInfo.live?.partyGaming ?: 0,
            userInfo.live?.partyGameSite ?: -1
        )
    }

    /**
     * 处理首页与热门页拨打按钮状态
     */
    fun callUserState(userBasic: UserBasicVo): Int {
        val invoke = invokeCallUserState(
            userBasic.online,
            userBasic.living,
            userBasic.liveType,
            userBasic.calling,
            userBasic.partyGaming,
            userBasic.partyGameSite
        )
        return if (invoke in NO_SHOW_CALL) {
            AppConst.NO
        } else {
            AppConst.YES
        }
    }

    private fun invokeResolveUserState(
        online: Int,
        living: Int? = null,
        liveType: Int? = null,
        calling: Int? = null,
        partyGaming: Int? = null,
        partyGameSite: Int? = null,
    ): Int {
        return if (calling == AppConst.YES) {
            USER_STATE_BUSY
        } else if (living == AppConst.YES) {
            when (liveType) {
                LiveConst.Type.PARTY_GAME_LIVE -> USER_STATE_GAME
                LiveConst.Type.PARTY_LIVE -> USER_STATE_PARTY
                LiveConst.Type.VIDEO_PARTY -> USER_STATE_PARTY_VIDEO
                LiveConst.Type.ONLY_LIVE, LiveConst.Type.LIVE_AND_MATCH -> USER_STATE_LIVE
                else -> USER_STATE_MATCH
            }
        } else {
            if (online == AppConst.YES) {
                if (partyGaming?.toBoolean() == true || partyGameSite != -1 && partyGameSite != null) {
                    USER_STATE_BUSY
                } else {
                    USER_STATE_ONLINE
                }
            } else {
                USER_STATE_OFFLINE
            }
        }
    }

    /**
     * 列表需要展示的用户状态
     */
    private fun invokeListUserState(
        online: Int,
        living: Int? = null,
        liveType: Int? = null,
        calling: Int? = null,
        partyGameStatus: Int? = null,
        partyGaming: Int? = null,
        partyGameSite: Int? = null,
    ): Int {
        return if (calling == AppConst.YES) {
            USER_STATE_BUSY
        } else if (living == AppConst.YES) {
            when (liveType) {
                LiveConst.Type.PARTY_GAME_LIVE -> {
                    if (partyGameStatus == UserConst.GameStatus.PLAYING) {
                        USER_GAME_PLAYING
                    } else {
                        USER_GAME_WAITING
                    }
                }

                LiveConst.Type.PARTY_LIVE -> USER_STATE_PARTY
                LiveConst.Type.VIDEO_PARTY -> USER_STATE_PARTY_VIDEO
                LiveConst.Type.ONLY_LIVE, LiveConst.Type.LIVE_AND_MATCH -> USER_STATE_LIVE
                else -> USER_STATE_MATCH
            }
        } else {
            if (online == AppConst.YES) {
                if (partyGaming?.toBoolean() == true || partyGameSite != -1 && partyGameSite != null) {
                    USER_STATE_BUSY
                } else {
                    USER_STATE_ONLINE
                }
            } else {
                USER_STATE_OFFLINE
            }
        }
    }

    private fun invokeCallUserState(
        online: Int,
        living: Int? = null,
        liveType: Int? = null,
        calling: Int? = null,
        partyGaming: Int? = null,
        partyGameSite: Int? = null,
    ): Int {
        return if (calling == AppConst.YES) {
            USER_STATE_BUSY
        } else if (living == AppConst.YES) {
            when (liveType) {
                LiveConst.Type.ONLY_LIVE -> USER_STATE_LIVE
                LiveConst.Type.PARTY_LIVE -> USER_STATE_PARTY
                LiveConst.Type.VIDEO_PARTY -> USER_STATE_PARTY_VIDEO
                LiveConst.Type.PARTY_GAME_LIVE -> USER_STATE_GAME
                else -> USER_STATE_MATCH
            }
        } else {
            if (online == AppConst.YES) {
                if (partyGaming?.toBoolean() == true || partyGameSite != -1 && partyGameSite != null) {
                    USER_STATE_GAME
                } else {
                    USER_STATE_ONLINE
                }
            } else {
                USER_STATE_OFFLINE
            }
        }
    }

    private val NO_SHOW_CALL = setOf(
        USER_STATE_LIVE,
        USER_STATE_OFFLINE,
        USER_STATE_BUSY,
        USER_GAME_PLAYING,
        USER_STATE_PARTY,
        USER_STATE_PARTY_VIDEO,
        USER_STATE_GAME
    )
}

/**
 * 判断当前是否是新开启了直播
 */
fun UserState.isStartedLive(userBasic: UserBasicVo): Boolean {
    return isStartedLive(userBasic.living ?: 0, userBasic.calling ?: 0)
}

/**
 * 判断当前是否是新开启了直播
 */
fun UserState.isStartedLive(oldLiving: Int, oldCalling: Int): Boolean {
    return living == 1 && oldLiving == 0 || calling == 0 && oldCalling == 1
}

/**
 * 判断当前是否是停止了直播
 */
fun UserState.isStoppedLive(userBasic: UserBasicVo): Boolean {
    return isStoppedLive(userBasic.living ?: 0, userBasic.calling ?: 0)
}

/**
 * 判断当前是否是停止了直播
 */
fun UserState.isStoppedLive(oldLiving: Int, oldCalling: Int): Boolean {
    return living == 0 && oldLiving == 1 || calling == 1 && oldCalling == 0
}

/**
 * 根据状态创建新的用户基础信息
 *
 * 如果[message]比当前的事件慢，将会无视
 */
fun UserBasicVo.copyState(message: UserStateMessage): UserBasicVo {
    val lastStateTime = lastStateTime
    return if (lastStateTime != null && lastStateTime > message.timestamp) {
        this
    } else {
        val state = message.state

        this.lastStateTime = message.timestamp

        copy(
            online = state.online,
            living = state.living,
            liveType = state.liveType,
            calling = state.calling,
            callType = state.callType,
            lastCallTime = state.lastCallTime,
            partyGameSite = state.partyGameSite,
            partyGameStatus = state.partyGameStatus,
            partyGameType = state.partyGameType,
            partyGaming = state.partyGaming,
            partySite = state.partySite
        )
    }
}

/**
 * 根据状态创建新的他人用户基础信息
 *
 * 这个数据太大只做修改
 */
fun InfoOtherResp.modifyState(message: UserStateMessage) {
    val lastStateTime = lastStateTime
    if (lastStateTime != null && lastStateTime > message.timestamp) {
        return
    }

    val state = message.state

    this.lastStateTime = message.timestamp

    online = state.online
    live?.living = state.living == 1
    live?.liveType = state.liveType
    call?.calling = state.calling == 1
    call?.callType = state.callType
    call?.lastCallTime = state.lastCallTime
    live?.partyGameSite = state.partyGameSite
    live?.partyGaming = state.partyGaming
    live?.partySite = state.partySite
    live?.partyGameType = state.partyGameType
    live?.partyGameStatus = state.partyGameStatus
    live?.stateBanner = state.stateBanner
    live?.roomId = state.roomId
}

/**
 * 获取当前显示的位置
 */
fun <T> RecyclerView.getDisplayPosition(data: List<T>): PositionWrapper? {
    if (data.isEmpty()) {
        return null
    }

    val firstPosition = getFirstPosition() ?: -1
    val lastPosition = getLastPosition() ?: -1

    //任意一个小于0或者全部等于0说明还没有渲染出来
    if (firstPosition < 0 || lastPosition < 0
        || (firstPosition == 0 && lastPosition == 0)
    ) {
        return null
    }

    val finalFirstPosition = max(firstPosition - 1, 0)
    val finalLastPosition = min(lastPosition + 1, data.size)

    //大于说明出现问题
    if (finalFirstPosition > finalLastPosition) {
        return null
    }

    return PositionWrapper(finalFirstPosition, finalLastPosition)
}

/**
 * 获取当前显示的索引位置，如果视图未渲染，则直接获取所有对象的索引
 */
fun <T> RecyclerView.getDisplayIndices(data: List<T>): IntRange {
    return getDisplayPosition(data)?.indices ?: return data.indices
}

/**
 * 序列包装
 */
class PositionWrapper(
    val firstPosition: Int,
    val lastPosition: Int,
) {

    val indices: IntRange
        get() = firstPosition until lastPosition

}